package com.flyqiu.common.property;

import com.flyqiu.common.std.FlyQiuBooleanFun;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * 实现基于 Map 的属性访问。
 * <p>
 * 此类提供了对 Map 中特定键值对的操作，包括读取、写入等基本属性操作。
 */
public class FiyQiuMapProperty implements FlyQiuBaseProperty {

    private final Object key;

    private final List<Annotation> mapAnnotations;

    /**
     * 构造一个新的 FiyQiuMapProperty 对象。
     *
     * @param key Map 中的键
     */
    public FiyQiuMapProperty(Object key) {
        this.key = key;
        mapAnnotations = new ArrayList<>();
    }

    /**
     * 判断属性是否可读。
     *
     * @return 如果属性可读，则返回 true；否则返回 false
     */
    @Override
    public boolean isRead() {
        return true;
    }

    /**
     * 判断属性是否可写。
     *
     * @return 如果属性可写，则返回 true；否则返回 false
     */
    @Override
    public boolean isWrite() {
        return true;
    }

    /**
     * 判断属性是否为静态属性。
     *
     * @return 如果属性为静态属性，则返回 true；否则返回 false
     */
    @Override
    public boolean isStatic() {
        return false;
    }

    /**
     * 获取属性的名称。
     *
     * @return 属性名称（即键的字符串表示）
     */
    @Override
    public String getName() {
        return String.valueOf(key);
    }

    /**
     * 获取属性的数据类型。
     *
     * @return 属性的数据类型（Map 类型）
     */
    @Override
    public Class<?> getType() {
        return Map.class;
    }

    @Override
    public <T extends Annotation> List<T> getAnnotations(FlyQiuBooleanFun<Annotation> filter, Function<Annotation, T> valueMapper) {
        if (filter == null) {
            throw new NullPointerException("filter cannot be null");
        }
        if (valueMapper == null) {
            throw new NullPointerException("filter cannot be null");
        }

        List<T> result = new ArrayList<>();
        for (Annotation annotation : mapAnnotations) {
            if (!filter.apply(annotation)) {
                continue;
            }
            result.add(valueMapper.apply(annotation));
        }
        return result;
    }

    /**
     * 获取属性的值。
     *
     * @param obj 对象实例（Map 对象）
     * @return 属性的值
     */
    @Override
    public Object getValue(Object obj) {
        Map<?, ?> map = (Map<?, ?>) obj;
        return map.get(key);
    }

    /**
     * 设置属性的值。
     *
     * @param obj 对象实例（Map 对象）
     * @param val 属性的新值
     */
    @Override
    public void setValue(Object obj, Object val) {
        Map<? super Object, ? super Object> map = (Map<? super Object, ? super Object>) obj;
        map.put((Object) key, val);
    }
}
